﻿using System;
using NUnit.Framework;

namespace KWatkins.FluentMoqBuilder.Tests
{
	[TestFixture]
	public sealed class HttpRequestBaseBuilderTests : AssertionHelper
	{
		#region AppRelativeCurrentExecutionFilePath
		[TestCase("/", "http://www.mrkwatkins.co.uk", Result = "~/")]
		[TestCase("/", "http://www.mrkwatkins.co.uk/Blog", Result = "~/Blog")]
		[TestCase("/", "http://www.mrkwatkins.co.uk/Blog/", Result = "~/Blog")]
		[TestCase("/Blog", "http://www.mrkwatkins.co.uk/Blog", Result = "~/")]
		[TestCase("/Blog", "http://www.mrkwatkins.co.uk/Blog/", Result = "~/")]
		public string AppRelativeCurrentExecutionFilePath(string applicationPath, string url)
		{
			return new HttpRequestBaseBuilder()
				.WithApplicationPath(applicationPath)
				.WithUrl(url)
				.Object
				.AppRelativeCurrentExecutionFilePath;
		}
		#endregion

		#region CurrentExecutionFilePath
		[TestCase("http://www.mrkwatkins.co.uk", Result = "/")]
		[TestCase("http://www.mrkwatkins.co.uk?key=value", Result = "/")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog?key=value", Result = "/Blog")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog/?key=value", Result = "/Blog")]
		public string CurrentExecutionFilePath(string url)
		{
			return new HttpRequestBaseBuilder()
				.WithUrl(url)
				.Object
				.CurrentExecutionFilePath;
		}
		#endregion

		#region FilePath
		[TestCase("http://www.mrkwatkins.co.uk", Result = "/")]
		[TestCase("http://www.mrkwatkins.co.uk?key=value", Result = "/")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog?key=value", Result = "/Blog")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog/?key=value", Result = "/Blog")]
		public string FilePath(string url)
		{
			return new HttpRequestBaseBuilder()
				.WithUrl(url)
				.Object
				.FilePath;
		}
		#endregion

		#region Path
		[TestCase("http://www.mrkwatkins.co.uk", Result = "/")]
		[TestCase("http://www.mrkwatkins.co.uk?key=value", Result = "/")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog?key=value", Result = "/Blog")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog/?key=value", Result = "/Blog/")]
		public string Path(string url)
		{
			return new HttpRequestBaseBuilder()
				.WithUrl(url)
				.Object
				.Path;
		}
		#endregion

		#region PathInfo
		[TestCase("http://www.mrkwatkins.co.uk", Result = "")]
		[TestCase("http://www.mrkwatkins.co.uk?key=value", Result = "")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog?key=value", Result = "")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog/?key=value", Result = "/")]
		public string PathInfo(string url)
		{
			return new HttpRequestBaseBuilder()
				.WithUrl(url)
				.Object
				.PathInfo;
		}
		#endregion

		#region RawUrl
		[TestCase("http://www.mrkwatkins.co.uk", Result = "/")]
		[TestCase("http://www.mrkwatkins.co.uk?key=value", Result = "/?key=value")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog?key=value", Result = "/Blog?key=value")]
		[TestCase("http://www.mrkwatkins.co.uk/Blog/?key=value", Result = "/Blog/?key=value")]
		public string RawUrl(string url)
		{
			return new HttpRequestBaseBuilder()
				.WithUrl(url)
				.Object
				.RawUrl;
		}
		#endregion

		#region QueryString
		[Test]
		public void QueryString()
		{
			var builder = new HttpRequestBaseBuilder()
				.WithUrl("http://www.mrkwatkins.co.uk");

			Expect(builder.Object.QueryString, Is.Not.Null.And.Empty);

			builder.WithUrl("http://www.mrkwatkins.co.uk?key=value");

			Expect(builder.Object.QueryString, Is.Not.Null);
			Expect(builder.Object.QueryString.Count, Is.EqualTo(1));
			Expect(builder.Object.QueryString["key"], Is.EqualTo("value"));
		}
		#endregion

		#region WithUrl
		[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
		[TestCase("", ExpectedException = typeof(ArgumentException))]
		public void WithUrl_String_InvalidUrl(string url)
		{
			MoqBuilder.HttpRequestBase.WithUrl(url);
		}
		[Test]
		public void WithUrl_String()
		{
			var builder = MoqBuilder.HttpRequestBase;
			Expect(builder.Object.Url, Is.EqualTo(new Uri("http://localhost/")));

			const string url = "http://www.mrkwatkins.co.uk/";
			Expect(builder.WithUrl(url), Is.EqualTo(builder));
			Expect(builder.Object.Url.ToString(), Is.EqualTo(url));
		}
		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void WithUrl_Uri_InvalidUrl()
		{
			MoqBuilder.HttpRequestBase.WithUrl((Uri)null);
		}
		[Test]
		public void WithUrl_Uri()
		{
			var builder = MoqBuilder.HttpRequestBase;
			Expect(builder.Object.Url, Is.EqualTo(new Uri("http://localhost/")));

			Uri url = new Uri("http://www.mrkwatkins.co.uk/");
			Expect(builder.WithUrl(url), Is.EqualTo(builder));
			Expect(builder.Object.Url, Is.EqualTo(url));
		}
		#endregion

		#region WithUrlReferrer
		[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
		[TestCase("", ExpectedException = typeof(ArgumentException))]
		public void WithUrlReferrer_String_InvalidUrlReferrer(string urlReferrer)
		{
			MoqBuilder.HttpRequestBase.WithUrlReferrer(urlReferrer);
		}
		[Test]
		public void WithUrlReferrer_String()
		{
			var builder = MoqBuilder.HttpRequestBase;
			Expect(builder.Object.UrlReferrer, Is.Null);

			const string urlReferrer = "http://www.mrkwatkins.co.uk/";
			Expect(builder.WithUrlReferrer(urlReferrer), Is.EqualTo(builder));
			Expect(builder.Object.UrlReferrer.ToString(), Is.EqualTo(urlReferrer));
		}
		[Test]
		[ExpectedException(typeof(ArgumentNullException))]
		public void WithUrlReferrer_Uri_InvalidUrlReferrer()
		{
			MoqBuilder.HttpRequestBase.WithUrlReferrer((Uri)null);
		}
		[Test]
		public void WithUrlReferrer_Uri()
		{
			var builder = MoqBuilder.HttpRequestBase;
			Expect(builder.Object.UrlReferrer, Is.Null);

			Uri urlReferrer = new Uri("http://www.mrkwatkins.co.uk/");
			Expect(builder.WithUrlReferrer(urlReferrer), Is.EqualTo(builder));
			Expect(builder.Object.UrlReferrer, Is.EqualTo(urlReferrer));
		}
		#endregion

		#region WithApplicationPath
		[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
		[TestCase("", ExpectedException = typeof(ArgumentException))]
		public void WithApplicationPath_InvalidApplicationPath(string applicationPath)
		{
			MoqBuilder.HttpRequestBase.WithApplicationPath(applicationPath);
		}
		[Test]
		public void WithApplicationPath()
		{
			var builder = MoqBuilder.HttpRequestBase;
			Expect(builder.Object.ApplicationPath, Is.EqualTo("/"));

			const string applicationPath = "/AppPath";
			Expect(builder.WithApplicationPath(applicationPath), Is.EqualTo(builder));
			Expect(builder.Object.ApplicationPath, Is.EqualTo(applicationPath));
		}
		#endregion

		#region WithPhysicalApplicationPath
		[TestCase(null, ExpectedException = typeof(ArgumentNullException))]
		[TestCase("", ExpectedException = typeof(ArgumentException))]
		public void WithPhysicalApplicationPath_InvalidApplicationPath(string applicationPath)
		{
			MoqBuilder.HttpRequestBase.WithPhysicalApplicationPath(applicationPath);
		}
		[Test]
		public void WithPhysicalApplicationPath()
		{
			var builder = MoqBuilder.HttpRequestBase;
			Expect(builder.Object.PhysicalApplicationPath, Is.EqualTo(@"c:\inetpub\wwwroot\"));

			const string physicalApplicationPath = @"d:\SomePath";
			Expect(builder.WithPhysicalApplicationPath(physicalApplicationPath), Is.EqualTo(builder));
			Expect(builder.Object.PhysicalApplicationPath, Is.EqualTo(physicalApplicationPath));
		}
		#endregion
	}
}
